package com.mm.fam.web.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mm.fam.common.utils.LoggerUtils;
import com.mm.fam.web.base.*;
import com.mm.fam.web.entity.SysMenu;
import com.mm.fam.web.entity.SysPermission;
import com.mm.fam.web.entity.SysRole;
import com.mm.fam.web.entity.ins.AuthMenuTreeIns;
import com.mm.fam.web.entity.ins.PermissionTreeIns;
import com.mm.fam.web.entity.ins.SingleUserRolesBoIns;
import com.mm.fam.web.entity.ins.UserRoleAllocationBoIns;
import com.mm.fam.web.service.OperateAccreditService;
import com.mm.fam.web.service.SysMenuService;
import com.mm.fam.web.service.SysPermissionService;
import com.mm.fam.web.service.SysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 角色管理
 */
@Api(value="角色模块", description="角色模块")
@RestController
@RequestMapping(value="/api/role")
public class SysRoleController {
	Logger logger = LoggerFactory.getLogger(SysRoleController.class);

	@Autowired
	SysMenuService sysMenuService;

	@Autowired
	SysRoleService sysRoleService;

	@Autowired
	SysPermissionService sysPermissionService;

	@Autowired
	OperateAccreditService operateAccreditService;

	@GetMapping(value = "/page")
	@ApiOperation(value="查询角色列表", notes="查询角色列表")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="query", required=false, name = "pageNo", value = "页码", dataType = "int"),
			@ApiImplicitParam(paramType="query", required=false, name = "pageSize", value = "页数", dataType = "int"),
			@ApiImplicitParam(paramType="query", required=false, name = "search", value = "搜索内容", dataType = "String")
	})
	public ResponseEntity<ResponseModel<IPage>> page(
			@RequestParam(value = "pageNo", defaultValue = "1") int pageNo,
	   		@RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
	   		@RequestParam(value = "search", defaultValue = "") String search) {
		ResponseEntity<ResponseModel<IPage>> re = null;
		try{
			IPage<SysRole> page = sysRoleService.page(pageNo, pageSize, search);
			re = ResponseUtil.success(page);
		}catch(Exception e){
			logger.error("SysRoleController.page", e);
			re = ResponseUtil.error("服务端异常" + e.getMessage());
		}
		return re;
	}

    @GetMapping(value = "/queryRoleListNoPage")
    @ApiOperation(value="查询角色列表部分页", notes="查询角色列表部分页")
	public ResponseEntity<ResponseModel<List<SysRole>>> queryRoleListNoPage(){
        ResponseEntity<ResponseModel<List<SysRole>>> re = null;
        try{
            re = sysRoleService.queryRoleListNoPage();
        }catch(Exception e){
            LoggerUtils.error(getClass(),"[queryRoleListNoPage]" + e.getMessage());
            re = ResponseUtil.error(CommonConstant.Message.ROLE_CODENAME_EXIST);
        }
        return re;
    }

	@PostMapping(value = "/saveOrUpdate")
	@ApiOperation(value="保存或修改角色信息", notes="保存或修改角色信息")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="body", required=false, name = "role", value = "角色对象", dataType = "SysRole"),
	})
	public ResponseEntity<ResponseModel<Object>> saveOrUpdate(@RequestBody SysRole role) {
		ResponseEntity<ResponseModel<Object>> re = null;
		try {
			String s = sysRoleService.saveRole(role);
			re = ResponseUtil.success(null);
		} catch (Exception e) {
			LoggerUtils.error(getClass(),"[角色更新或者删除]" + e.getMessage());
			re = ResponseUtil.error(CommonConstant.Message.ROLE_CODENAME_EXIST);
		}
		return re;
	}

	@PostMapping(value = "/delete")
	@ApiOperation(value="逻辑删除角色信息", notes="逻辑删除角色信息")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="body", required=false, name = "ids", value = "角色id数组", dataType = "map"),
	})
	public ResponseEntity<ResponseModel<Object>> delete(@RequestBody Map<String, Object>param) {
		ResponseEntity<ResponseModel<Object>> re = null;
		try {
			List<Integer> ids = (List<Integer>) param.get("ids");
			for(Integer id:ids){
				//删除角色前需确定该角色是否已被分配权限，如已分配需先解除角色权限关系
				int permissionCount = sysRoleService.queryPerAllocationNumOfRole(id);
				//删除角色前需要先判断该角色是否被用户占用
				int userCount = sysRoleService.queryRoleByUserCount(id);
				if (permissionCount>0) {
					re = ResponseUtil.error(CommonConstant.Message.ROLE_EXIST_PERMISSION);
				}else if (userCount>0){
					re = ResponseUtil.error(CommonConstant.Message.ROLE_EXIST_USER);
				}else {
					sysRoleService.removeById(id);
					re = ResponseUtil.success(CommonConstant.Message.OPTION_SUCCESS);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			LoggerUtils.error(getClass(),"[role delete]" + e.getMessage());
			re = ResponseUtil.error(CommonConstant.Message.OPTION_FAILURE);
		}
		return re;
	}

	@ApiOperation(value="根据角色信息查询操作权限", notes="根据角色信息查询操作权限")
	@GetMapping(value = "/queryOperateAccreditList")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="query", required=true, name = "roleId", value = "角色id", dataType = "int")
	})
	public ResponseEntity<ResponseModel<Object>> queryOperateAccreditList(Integer roleId){
		ResponseEntity<ResponseModel<Object>> re = null;
		try{
			re = operateAccreditService.queryOperateAccreditList(roleId);
		}catch(Exception e){
			LoggerUtils.error(getClass(), e.getMessage());
			re = ResponseUtil.error(CommonConstant.Message.OPTION_FAILURE);
		}
		return re;
	}

	@PostMapping(value = "/saveRoleOperateAccredit")
	@ApiOperation(value="根据角色信息查询操作权限", notes="根据角色信息查询操作权限")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="query", required=true, name = "roleId", value = "角色id", dataType = "int")
	})
	public ResponseEntity<ResponseModel<Object>> saveRoleOperateAccredit(@RequestBody List<Map<String, Integer>> param){
		ResponseEntity<ResponseModel<Object>> re = null;
		try{
			re = operateAccreditService.saveRoleOperateAccredit(param);
		}catch(Exception e){
			LoggerUtils.error(getClass(), e.getMessage());
			re = ResponseUtil.error(CommonConstant.Message.OPTION_FAILURE);
		}
		return re;
	}

	@Deprecated
	@GetMapping(value = "/query/{id}")
	@ApiOperation(value="根据id查询角色信息", notes="根据id查询角色信息")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="path", required=false, name = "id", value = "角色id", dataType = "int"),
	})
	public ResponseEntitySelf<SysRole> query(HttpServletRequest request, @PathVariable("id") Integer id) {
		ResponseEntitySelf<SysRole> res = new ResponseEntitySelf<>();
		try {
			SysRole role=sysRoleService.getById(id);
			res.success(CommonConstant.Message.OPTION_SUCCESS);
			res.setData(role);
		} catch (Exception e) {
			LoggerUtils.error(getClass(),"[role get]" + e.getMessage());
			res.failure(CommonConstant.Message.OPTION_FAILURE);
		}
		return res;
	}

	@Deprecated
	@GetMapping(value = "/pageUserRoles")
	@ApiOperation(value="分页查询所有用户已分配角色", notes="分页查询所有用户已分配角色")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="query", required=false, name = "current", value = "页码", dataType = "int"),
			@ApiImplicitParam(paramType="query", required=false, name = "pageSize", value = "条数", dataType = "int"),
			@ApiImplicitParam(paramType="query", required=false, name = "search", value = "搜索条件", dataType = "string"),
			@ApiImplicitParam(paramType="query", required=false, name = "order", value = "排序", dataType = "string")
	})
	public ResponseEntity<ResponseModel<IPage>> pageUserRoles(@RequestParam(value = "current", defaultValue = "1") int current,
                                                              @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
                                                              @RequestParam(value = "search", defaultValue = "") String search,
                                                              @RequestParam(value = "order", defaultValue = "") String order) {
		ResponseEntity<ResponseModel<IPage>> re = null;
		try {
			IPage<UserRoleAllocationBoIns> page = sysRoleService.queryUserRoleByPage(search, current, pageSize, order);
			for(UserRoleAllocationBoIns userRoleAllocationBo:page.getRecords()){
				userRoleAllocationBo.roleVerToHor();   //查询结果行专列
			}
			re = ResponseUtil.success(page);
		} catch (RuntimeException e) {
			LoggerUtils.error(getClass(),"[sysrole pageUserRoles]" + e.getMessage());
			re = ResponseUtil.error("获取列表失败");
		}
		return re;
	}

	/**
	 * 更新用户角色关系
	 * @return
	 */
	@Deprecated
	@PostMapping(value = "/updateUserRoles")
	@ApiOperation(value="修改用户角色", notes="修改用户角色")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="body", required=false, name = "current", value = "页码", dataType = "int"),
	})
	public ResponseEntitySelf<String> updateUserRoles(@RequestBody Map<String, Object>param) {
		ResponseEntitySelf<String> res=null;
		try {
			res = new ResponseEntitySelf<String>();

			Integer userId = (Integer)param.get("userId");
			List<Integer> roleIds= (List<Integer>) param.get("roleIds");
			sysRoleService.updateUserRoles(userId, roleIds);
			res.setMsg(CommonConstant.Message.OPTION_SUCCESS);
		} catch (RuntimeException e) {
			e.printStackTrace();
			res.setMsg(e.getMessage());
			LoggerUtils.error(getClass(),"[sys updateUserRoles]" + e.getMessage());
		}
		return res;
	}

	@Deprecated
	@GetMapping(value = "/querySingleUserRole/{userId}")
	@ApiOperation(value="查询单个用户角色分配情况", notes="查询单个用户角色分配情况")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="path", required=false, name = "userId", value = "用户id", dataType = "int"),
	})
	public ResponseList<SingleUserRolesBoIns> querySingleUserRole(@PathVariable("userId") Integer userId) {
		ResponseList<SingleUserRolesBoIns> res=new ResponseList<SingleUserRolesBoIns>();
		try {
			List<SingleUserRolesBoIns> singleUserRoleAllocationBos = sysRoleService.queryRoleAllocationByUserId(userId);
			res.setData(singleUserRoleAllocationBos);
		} catch (RuntimeException e) {
			res.failure(CommonConstant.Message.OPTION_FAILURE);
			LoggerUtils.error(getClass(),"[querySingleUserRole]" + e.getMessage());
		}
		return res;
	}

	@Deprecated
	@GetMapping(value = "/deleteRoleByUserId/{userId}")
	@ApiOperation(value="清空单个用户角色", notes="清空单个用户角色")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="path", required=false, name = "userId", value = "用户id", dataType = "int"),
	})
	public ResponseEntitySelf<String> deleteRoleByUserId(@PathVariable("userId") Integer userId) {

		ResponseEntitySelf<String> res = new ResponseEntitySelf<>();
		try {
			sysRoleService.deleteAllRoleByUserId(userId);
			res.success(CommonConstant.Message.OPTION_SUCCESS);
		} catch (Exception e) {
			LoggerUtils.error(getClass(),"[role get]" + e.getMessage());
			res.failure(CommonConstant.Message.OPTION_FAILURE);
		}
		return res;
	}

	@Deprecated
	@GetMapping(value = "/getPermissionTreeByRoleId")
	@ApiOperation(value="得到某个角色的权限树", notes="得到某个角色的权限树")
	@ApiImplicitParams({
			@ApiImplicitParam(paramType="query", required=false, name = "roleId", value = "角色id", dataType = "string"),
	})
	public ResponseList<PermissionTreeIns> getPermissionTreeByRoleId(@RequestParam(value = "roleId") Integer roleId){
		ResponseList<PermissionTreeIns> res = new ResponseList<PermissionTreeIns>();
		try {
			List<SysPermission>permissions=sysPermissionService.getPermissionByRoleId(roleId);

			Map<Integer, SysPermission>mapPermissions=new HashMap<Integer, SysPermission>();
			for(SysPermission permission: permissions){
				mapPermissions.put(permission.getId(), permission);
			}
			List<PermissionTreeIns> permissionTrees=sysPermissionService.getPermissionTree(roleId);

			setPermissionTree(permissionTrees,mapPermissions);
			res.setData(permissionTrees);
		} catch (Exception e) {
			LoggerUtils.error(getClass(),"[role gePermissionTree]" + e.getMessage());
			res.failure(CommonConstant.Message.OPTION_FAILURE);
		}
		return res;
	}


	/**
	 * 设置权限树 状态(设置 是否选中)
	 * @param trees
	 * @param mapPermissions
	 */
	private void setPermissionTree(List<PermissionTreeIns> trees,Map<Integer, SysPermission>mapPermissions){
		if(trees==null || trees.isEmpty())
			return;
		for(PermissionTreeIns tree: trees){
			if(mapPermissions.containsKey(tree.getId())){
				tree.setChecked(true);
			}
			if(tree.getChildren()!=null && !tree.getChildren().isEmpty()){
				tree.setIsParent(true);
				setPermissionTree(tree.getChildren(),mapPermissions);
			}

		}
		return;
	}

	/**
	 * 设置权限树 状态(设置 是否选中)
	 * @param trees 菜单树
	 * @param mapHasMenusMenus 具有权限的菜单
	 */
	private void setMenuTree(List<AuthMenuTreeIns> trees, Map<String, SysMenu>mapHasMenusMenus){
		if(trees==null || trees.isEmpty())
			return;
		for(AuthMenuTreeIns tree: trees){
			if(mapHasMenusMenus!=null && mapHasMenusMenus.containsKey(tree.getId())){
				tree.setChecked(true);
			}
			if(tree.getChildren()!=null && !tree.getChildren().isEmpty()){
				tree.setIsParent(true);
				setMenuTree(tree.getChildren(),mapHasMenusMenus);
			}
		}
		return;
	}
}
